package com.evaluation.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.evaluation.common.Result;
import com.evaluation.config.WeChatCpConfig;
import com.evaluation.entity.Weixin;
import com.evaluation.service.WeixinService;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.bean.WxCpOauth2UserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

/**
 * 企业微信登录控制器
 */
@Slf4j
@Controller
@RequestMapping("/wechat")
public class WeChatLoginController {

    @Autowired
    private WxCpService wxCpService;

    @Autowired
    private WeChatCpConfig weChatCpConfig;
    @Autowired
    private WeixinService weixinService;

    /**
     * 企业微信登录入口
     * 生成授权链接并重定向到企业微信
     */
    @GetMapping("/login")
    public void login(HttpServletResponse response) throws IOException {
        log.info("开始企业微信登录流程");

        try {
            // 构建企业微信OAuth2授权链接
            String authUrl = wxCpService.getOauth2Service().buildAuthorizationUrl(
                    weChatCpConfig.getRedirectUri(),
                    null  // state参数，可以用于防CSRF攻击
            );

            log.info("企业微信授权链接: {}", authUrl);

            // 重定向到企业微信授权页面
            response.sendRedirect(authUrl);

        } catch (Exception e) {
            log.error("生成企业微信授权链接失败", e);
            String errorMsg = "企业微信授权登录失败，请联系管理员。无法生成授权链接。";
            response.sendRedirect("/evaluation/wechat-error.html?error=" +
                    URLEncoder.encode(errorMsg, "UTF-8") + "&code=WX_AUTH_LINK_ERROR");
        }
    }

    /**
     * 企业微信授权回调处理
     * 处理企业微信返回的授权码，获取用户信息并完成登录
     */
    @GetMapping("/callback")
    public void callback(@RequestParam("code") String code,
                         @RequestParam(value = "state", required = false) String state,
                         HttpServletRequest request,
                         HttpServletResponse response) throws IOException {

        log.info("企业微信回调，code: {}, state: {}", code, state);

        if (StrUtil.isBlank(code)) {
            log.error("企业微信回调code为空");
            String errorMsg = "企业微信授权登录失败，请联系管理员。授权码为空，请重新尝试。";
            response.sendRedirect("/evaluation/wechat-error.html?error=" +
                    URLEncoder.encode(errorMsg, "UTF-8") + "&code=WX_CODE_EMPTY");
            return;
        }

        try {
            // 通过code获取用户信息
            WxCpOauth2UserInfo userInfo = wxCpService.getOauth2Service().getUserInfo(code);
            log.info("获取到企业微信用户信息: {}", JSONUtil.toJsonStr(userInfo));

            // 根据企业微信账号查询用户信息
            Weixin weixin = weixinService.getByQywx(userInfo.getUserId());

            if (weixin != null) {
                log.info("企业微信登录成功，用户ID: {}", userInfo.getUserId());
                // 将用户信息保存到session中
                HttpSession session = request.getSession();
                session.setAttribute("currentUser", weixin);
                session.setAttribute("currentUserName", weixin.getJsxm());
                session.setMaxInactiveInterval(3600 * 24); // 24小时超时
                // 登录成功，重定向到首页
                response.sendRedirect("/evaluation/static/h5/index.html");
            } else {
                log.error("企业微信登录失败: 用户不存在，请联系管理员添加用户信息");
                response.sendRedirect("/evaluation/wechat-error.html?error=" +
                        URLEncoder.encode("用户不存在，请联系管理员添加用户信息", "UTF-8") +
                        "&code=WX_LOGIN_FAILED");
            }

        } catch (Exception e) {
            log.error("企业微信登录回调处理失败", e);
            String errorMsg = "企业微信授权登录失败，请联系管理员。系统异常，请稍后重试。";
            response.sendRedirect("/evaluation/wechat-error.html?error=" +
                    URLEncoder.encode(errorMsg, "UTF-8") + "&code=WX_CALLBACK_ERROR");
        }
    }

    /**
     * 获取当前登录用户信息
     */
    @GetMapping("/userinfo")
    @ResponseBody
    public Result<?> getUserInfo(HttpSession session) {
        try {
            Object userInfo = session.getAttribute("userInfo");
            if (userInfo != null) {
                return Result.success(userInfo);
            } else {
                return Result.error("用户未登录");
            }
        } catch (Exception e) {
            log.error("获取用户信息失败", e);
            return Result.error("企业微信授权登录失败，请联系管理员。获取用户信息异常，请重新登录或联系技术支持。");
        }
    }

    /**
     * 退出登录
     */
    @GetMapping("/logout")
    @ResponseBody
    public Result<?> logout(HttpSession session) {
        try {
            session.invalidate();
            return Result.success("退出登录成功");
        } catch (Exception e) {
            log.error("退出登录失败", e);
            return Result.error("企业微信授权登录失败，请联系管理员。退出登录异常，请关闭浏览器或联系技术支持。");
        }
    }

    /**
     * 企业微信错误页面
     * 用于显示企业微信登录相关的错误信息
     */
    @GetMapping("/error")
    public void showErrorPage(@RequestParam(value = "error", required = false) String error,
                              @RequestParam(value = "code", required = false) String code,
                              HttpServletResponse response) throws IOException {

        log.info("显示企业微信错误页面，错误信息: {}, 错误代码: {}", error, code);

        // 构建错误页面URL
        StringBuilder errorUrl = new StringBuilder("/evaluation/wechat-error.html");

        if (StrUtil.isNotBlank(error) || StrUtil.isNotBlank(code)) {
            errorUrl.append("?");

            try {
                if (StrUtil.isNotBlank(error)) {
                    errorUrl.append("error=").append(URLEncoder.encode(error, "UTF-8"));
                }

                if (StrUtil.isNotBlank(code)) {
                    if (StrUtil.isNotBlank(error)) {
                        errorUrl.append("&");
                    }
                    errorUrl.append("code=").append(URLEncoder.encode(code, "UTF-8"));
                }
            } catch (UnsupportedEncodingException e) {
                log.error("URL编码失败", e);
                // 使用默认错误页面
                errorUrl = new StringBuilder("/evaluation/wechat-error.html");
            }
        }

        response.sendRedirect(errorUrl.toString());
    }

    /**
     * 处理异常并返回统一错误信息
     */
    private String buildErrorMessage(String operation, Exception e) {
        String baseMsg = "企业微信授权登录失败，请联系管理员。";
        String detailMsg = operation + "异常";

        if (e instanceof WxErrorException) {
            WxErrorException wxe = (WxErrorException) e;
            detailMsg = operation + "失败：" + wxe.getError().getErrorMsg();
        }

        return baseMsg + detailMsg;
    }

    /**
     * 构建错误重定向URL
     */
    private String buildErrorRedirectUrl(String errorMessage, String errorCode) {
        try {
            return "/evaluation/wechat-error.html?error=" +
                    URLEncoder.encode(errorMessage, "UTF-8") +
                    "&code=" + URLEncoder.encode(errorCode, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            log.error("构建错误重定向URL失败", e);
            return "/evaluation/wechat-error.html?error=企业微信授权登录失败，请联系管理员&code=UNKNOWN_ERROR";
        }
    }
}

